
#include "Client.h"
#include "App.h"
#include "Random.h"
#include "log.h"
int Port = 7777;

CClient* CClient::client = 0;

enum ENUMPacketIDs
{
	GameCommands = 0,
	LobbyCommands
};

enum NetworkCommands
{
	CONNECT = 0,
	DISCONNECT
};
enum InGameCommands
{
	MOVE_LEFT = 0,
	MOVE_RIGHT,
	MOVE_JUMP,
	STOP_MOVE_LEFT,
	STOP_MOVE_RIGHT,
	STOP_JUMPING,
	CAST_PROJECTILE
};

CClient::CClient()
{
	 
	PID = 0;
	connected = false;
}

CClient& CClient::getInstance()
{
	if(!client)
		client = new CClient();

	return *client;
}

// Function used to connect to the server.
bool CClient::Connect()
{

    do
    {
		// Add some form of input to set the server address instead of a pre-set string.
		ServerAddress = IP;
    }
    while (!ServerAddress.IsValid());

    // Connect to the specified server
    if (Client.Connect((unsigned short)atoi(port.c_str()), ServerAddress) != sf::Socket::Done)
        return false;

	// If connection was successfull the first package will be a package containing player ID.
	// receive it, and set myID to the received ID.
	if(Client.Receive(onConnect) == sf::Socket::Done)
	{	
		onConnect >> myID;
		CClient::myID = myID;
	}
	else
		return false;
	
	// Asuming that your playerID will be the number of players in the game
	// add a new player for each participant. Might need changing to implement disconnects etc.
	for (int i = 0; i <= myID; i++)
	{
		CApp::addPlayer();
	}

	// Set the connected value to true.
	connected = true;

	// Add the connection to the selector.
	selector.Add(Client);

	
	LOGW("Time: " << SDL_GetTicks() << " - " << "connected");
	return true;
}

void CClient::RunLobby()
{
	
	if(connected)
	{
		// If there are packets incomming receive them, if not time out after 0,01 seconds.
		if(selector.Wait(0.5f) > 0)
		{
		NbSockets = selector.Wait();
		
			for (unsigned int i = 0; i < NbSockets; ++i)
			{
				// Only Client socket will be used on the client side.
				// thus no need to have a socket for use for the ready socket.
				// It will always be Client.
				ReSend.Clear();

				// If disconnected, set connected to false.
				if(Client.Receive(ReSend) == sf::Socket::Disconnected)
				{
					connected = false;
				}
		
				// If the packet is readable.
				ReSend >> packetID >> entityID  >> playerID >> command >> targX >> targY >> name >> items; //Reads the recieved packet into different objects.
				{
					LOGW("Packet: " << packetID << " EntityID: " << entityID << " PlayerID: " << playerID << " CommandID: " << command << " TargX: " << targX << " TargY: " << targY << " Name: " << name);
					// Check the packetID
					switch(packetID)
					{
						case 1: // Packet ID 1, Lobby packet. 
							{
								switch(command)	// Check the commandID. ToDo: Change 0, 1 etc. to the corresponding command name from the ENUM.
								{
									case CONNECT: // Checks if there is a new player connected, then sends the item and name of your player to server. server then changes its item and name on the playerID, and sends to all connected clients. with case command 8.
									{

										if(CEntity::PlayerList.size()<= playerID) // if the playerID is less than the size of the playerlist, add a player.
										{	
											CApp::addPlayer();
										}

										char *a=new char[CAppState::name.size()]; //Gets the name of your player.
										a[CAppState::name.size()]=0;
										memcpy(a,CAppState::name.c_str(),CAppState::name.size());
										CClient::getInstance().SendPacket(1,0,CClient::myID,8,0,0,a,CAppState::items); //Sends to server a packet containing name, and the choosen items.
										break;

									}
									case DISCONNECT:
									{
										if(CApp::removePlayer(playerID))
										{
											if(playerID < myID)
											{
												myID--;
											}
										}
										break;
									}

									case 8:
										{
											//Packet is recieved containing the name and items of a different player, now the client adds the name and items to the playerlist in the client.
											CEntity::PlayerList.at(playerID)->name = name;
											CEntity::PlayerList.at(playerID)->itemArray[0] = items[0];
											CEntity::PlayerList.at(playerID)->itemArray[1] = items[1];
											CEntity::PlayerList.at(playerID)->itemArray[2] = items[2];
											CEntity::PlayerList.at(playerID)->itemArray[3] = items[3];
											CEntity::PlayerList.at(playerID)->itemArray[4] = items[4];

											if(CEntity::PlayerList.at(playerID)->health == 100)// Checks if playerhealth already has been substracted, this runs everytime a player joins, so the if test if needed.
											{
												for (int i = 0; i < 5; i++)
												{
													#pragma region ItemsEffects
												char cItemID = CEntity::PlayerList.at(playerID)->itemArray[i];
												int iItemID = atoi(&cItemID);
												std::string effect = itemList.effects[iItemID];
									
												//Health
												if(effect.at(0) == '-') 
												{
													CEntity::PlayerList.at(playerID)->health -= atoi(&effect.at(1));
												}
											
												else if(effect.at(0) == '+')
												{
													CEntity::PlayerList.at(playerID)->health += atoi(&effect.at(1));
												}		

												//CastSpeed
												if(effect.at(4) == '-') 
												{	
													if(CEntity::PlayerList.at(playerID)->castTime -= atoi(&effect.at(5))<6)
													{	
														CEntity::PlayerList.at(playerID)->castTime = 5;
													}	
												}
											
												if(effect.at(4) == '+')
												{
													CEntity::PlayerList;
													CEntity::PlayerList.at(playerID)->castTime += atoi(&effect.at(5));		
												}	

												//MoveSpeed
												if(effect.at(8) == '-') 
												{
													if(CEntity::PlayerList.at(playerID)->MaxSpeedX -= atoi(&effect.at(9))< 2)
													{		
														CEntity::PlayerList.at(playerID)->MaxSpeedX = 1;
													}
												}
											
												if(effect.at(8) == '+')
												{
													CEntity::PlayerList;
													CEntity::PlayerList.at(playerID)->MaxSpeedX += atoi(&effect.at(9));	
												}	
												#pragma endregion //For each item in the recieved packet,get the effects from Items.cpp and add the item to playerList.
												}
	
												CEntity::PlayerList.at(playerID)->maxHealth = CEntity::PlayerList.at(playerID)->health;	
											}
											break;
										}
								
									default:
										{
										}
									}

								break;
							}
							// End packetID case 0. Movement commands.

							// End packetID case 1. Lobby commands.
						}
				} // End if
			} // End for
		} // End if
	} // End if
}

void CClient::RunClient()
{
	if(connected)
	{
		// If there are packets incomming receive them, if not time out after 0,01 seconds.
		if(selector.Wait(0.01f) > 0)
		{
		NbSockets = selector.Wait();
		
			for (unsigned int i = 0; i < NbSockets; ++i)
			{
				// Only Client socket will be used on the client side.
				// thus no need to have a socket for use for the ready socket.
				// It will always be Client.
				ReSend.Clear();

				// If disconnected, set connected to false.
				if(Client.Receive(ReSend) == sf::Socket::Disconnected)
				{
					connected = false;
				}
		
				// If the packet is readable.
				if(ReSend >> packetID >> entityID >> playerID >> command >> targX >> targY >> name)
				{
					// Check the packetID
					switch(packetID)
					{
						case 0: // Packet ID 0, command packet. Currently contains movement and casting commands.
							{
								switch(command)	// Check the commandID. ToDo: Change 0, 1 etc. to the corresponding command name from the ENUM.
								{
								case 0:
								{
									LOGW("Time: " << SDL_GetTicks() << " - " << "Move Left Packet from: " << playerID);
									CEntity::PlayerList.at(playerID)->MoveLeft = true;
									CEntity::PlayerList.at(playerID)->X = targX;
									CEntity::PlayerList.at(playerID)->Y = targY;
									break;
								}
							case 1:
								{
									LOGW("Time: " << SDL_GetTicks() << " - " << "Move Right Packet from: " << playerID);
									CEntity::PlayerList.at(playerID)->MoveRight = true;
									CEntity::PlayerList.at(playerID)->X = targX;
									CEntity::PlayerList.at(playerID)->Y = targY;
									break;
								}
							case 2:
								{
									LOGW("Time: " << SDL_GetTicks() << " - " << "Jump Packet from: " << playerID);
									CEntity::PlayerList.at(playerID)->Jump();
									CEntity::PlayerList.at(playerID)->X = targX;
									CEntity::PlayerList.at(playerID)->Y = targY;
									break;
								}
							case 3:
								{
									LOGW("Time: " << SDL_GetTicks() << " - " << "Stop Move Left Packet from: " << playerID);
									CEntity::PlayerList.at(playerID)->MoveLeft = false;
									CEntity::PlayerList.at(playerID)->X = targX;
									CEntity::PlayerList.at(playerID)->Y = targY;
									break;
								}
							case 4:
								{
									LOGW("Time: " << SDL_GetTicks() << " - " << "Stop Move Right Packet from: " << playerID);
									CEntity::PlayerList.at(playerID)->MoveRight = false;
									CEntity::PlayerList.at(playerID)->X = targX;
									CEntity::PlayerList.at(playerID)->Y = targY;
									break;
								}
							case 5:
								{
									LOGW("Time: " << SDL_GetTicks() << " - " << "Case 5 Packet from: " << playerID);
									/*CEntity::PlayerList.at(playerID)->jumping = false;
									CEntity::PlayerList.at(playerID)->CanJump = false;
									CEntity::PlayerList.at(playerID)->X = targX;
									CEntity::PlayerList.at(playerID)->Y = targY;*/
									break;
								}
							case 6:
								{
									LOGW("Time: " << SDL_GetTicks() << " - " << entityID << " Projectile Packet from: " << playerID);
									// Projectiles are working as intended in the final versions, it sends the target when Q is clicked
									// So you have to aim when you click Q , instead of being able to move your mouse up
									// until the spell is finished.
									switch(entityID)
								{
									case 0:
										{
											break;
										}
									case 1:
										{
											
											if(!CEntity::PlayerList.at(playerID)->casting)
											{
												CEntity::PlayerList.at(playerID)->casting = true;
												CEntity::PlayerList.at(playerID)->spellID = entityID;
												CEntity::PlayerList.at(playerID)->castStart = SDL_GetTicks();
												CEntity::PlayerList.at(playerID)->targetX = targX;
												CEntity::PlayerList.at(playerID)->targetY = targY;
												CEntity::PlayerList.at(playerID)->castEnd = CEntity::PlayerList.at(playerID)->castStart + 1000;
											}
											break;
										}
									case 2:
										{
											
											if(!CEntity::PlayerList.at(playerID)->casting)
											{
												CEntity::PlayerList.at(playerID)->casting = true;
												CEntity::PlayerList.at(playerID)->spellID = entityID;
												CEntity::PlayerList.at(playerID)->castStart = SDL_GetTicks();
												CEntity::PlayerList.at(playerID)->targetX = targX;
												CEntity::PlayerList.at(playerID)->targetY = targY;
												CEntity::PlayerList.at(playerID)->castEnd = CEntity::PlayerList.at(playerID)->castStart + 1000;
											}
											break;
										}
									case 3:
										{
											break;
										}
									case 4:
										{
											if(!CEntity::PlayerList.at(playerID)->casting)
											{
												CEntity::PlayerList.at(playerID)->casting = true;
												CEntity::PlayerList.at(playerID)->spellID = entityID;
												CEntity::PlayerList.at(playerID)->castStart = SDL_GetTicks();
												CEntity::PlayerList.at(playerID)->targetX = targX;
												CEntity::PlayerList.at(playerID)->targetY = targY;
												CEntity::PlayerList.at(playerID)->castEnd = CEntity::PlayerList.at(playerID)->castStart + 500;
											}
											break;
										}
									case 5:
									{
										if(!CEntity::PlayerList.at(playerID)->casting)
										{
											CEntity::PlayerList.at(playerID)->casting = true;
											CEntity::PlayerList.at(playerID)->spellID = entityID;
											CEntity::PlayerList.at(playerID)->castStart = SDL_GetTicks();
											CEntity::PlayerList.at(playerID)->targetX = targX;
											CEntity::PlayerList.at(playerID)->targetY = targY;
											CEntity::PlayerList.at(playerID)->castEnd = SDL_GetTicks();
										}
										break;
									}
									}
								break;
								}
								case 7:
								{
									LOGW("Time: " << SDL_GetTicks() << " - " << "Case 7 Packet from: " << playerID);

								break;		
								}
								case 9: // Skipping case 8 due to it being used by items, and might some time be needed in this loop as well.
									{
										LOGW("Time: " << SDL_GetTicks() << " - " << "Case 9 collision Packet from: " << playerID);
										NetworkCol EntityCol;

										EntityCol.A = playerID;
										EntityCol.B = entityID;

										NetworkCol::NetworkEntityColList.push_back(EntityCol);
										break;
									}
								case 10:
									{
										LOGW("Time: " << SDL_GetTicks() << " - " << "Case 10 collision Packet from: " << playerID);
										NetworkCol EntityCol;

										EntityCol.A = playerID;
										EntityCol.B = entityID;

										NetworkCol::NetworkEntityColList.push_back(EntityCol);
										break;
									}
								case 11:
									{
										LOGW("Time: " << SDL_GetTicks() << " - " << entityID << " Case 11 casting Packet from: " << playerID);
										if(entityID == 5)
										{
											CEntity::PlayerList.at(playerID)->targetX = targX;
											CEntity::PlayerList.at(playerID)->targetY = targY;
										}
										CEntity::PlayerList.at(playerID)->CastProjectile(entityID);
										break;
									}
							default:
								{
								}
							}
							break;
						}
							// End packetID case 0. Movement commands.
						case 1: // Packet ID 1, Lobby packet.
							{
								LOGW("Time: " << SDL_GetTicks() << " - " << "Case 1 in game Packet from: " << playerID);
								switch(command)	// Check the commandID. ToDo: Change 0, 1 etc. to the corresponding command name from the ENUM.
								{
									case CONNECT:
									{
										CApp::addPlayer();

										char *a=new char[CAppState::name.size()];
										a[CAppState::name.size()]=0;
										memcpy(a,CAppState::name.c_str(),CAppState::name.size());
										CClient::getInstance().SendPacket(1,0,CClient::myID,8,0,0,a,CAppState::items);
										break;
									}
									case DISCONNECT:
									{
										if(CApp::removePlayer(playerID))
										{
											if(playerID < myID)
											{
												myID--;
											}
										}
										break;
									}
									case 8:
										{
											LOGW("Time: " << SDL_GetTicks() << " - " << "Case 8 Packet from: " << playerID);
											if(playerID > CEntity::PlayerList.size()-1)
												CApp::addPlayer();

											CEntity::PlayerList.at(playerID)->name = name;
											CEntity::PlayerList.at(playerID)->itemArray[0] = items[0];
											CEntity::PlayerList.at(playerID)->itemArray[1] = items[1];
											CEntity::PlayerList.at(playerID)->itemArray[2] = items[2];
											CEntity::PlayerList.at(playerID)->itemArray[3] = items[3];
											CEntity::PlayerList.at(playerID)->itemArray[4] = items[4];

											if(CEntity::PlayerList.at(playerID)->health == 100)// Checks if playerhealth already has been substracted, this runs everytime a player joins, so the if test if needed.
											{
												for (int i = 0; i < 5; i++)
												{
													#pragma region ItemsEffects
													char cItemID = CEntity::PlayerList.at(playerID)->itemArray[i];
													int iItemID = atoi(&cItemID);
													std::string effect = itemList.effects[iItemID];
									
													//Health
													if(effect.at(0) == '-') 
													{
														CEntity::PlayerList.at(playerID)->health -= atoi(&effect.at(1));
													}
											
													else if(effect.at(0) == '+')
													{
														CEntity::PlayerList.at(playerID)->health += atoi(&effect.at(1));
													}		

													//CastSpeed
													if(effect.at(4) == '-') 
													{	
														if(CEntity::PlayerList.at(playerID)->castTime -= atoi(&effect.at(5))<6)
														{	
															CEntity::PlayerList.at(playerID)->castTime = 5;
														}	
													}
											
													if(effect.at(4) == '+')
													{
														CEntity::PlayerList;
														CEntity::PlayerList.at(playerID)->castTime += atoi(&effect.at(5));		
													}	

													//MoveSpeed
													if(effect.at(8) == '-') 
													{
														if(CEntity::PlayerList.at(playerID)->MaxSpeedX -= atoi(&effect.at(9))< 2)
														{		
															CEntity::PlayerList.at(playerID)->MaxSpeedX = 1;
														}
													}
											
													if(effect.at(8) == '+')
													{
														CEntity::PlayerList;
														CEntity::PlayerList.at(playerID)->MaxSpeedX += atoi(&effect.at(9));	
													}	
													#pragma endregion //For each item in the recieved packet,get the effects from Items.cpp and add the item to playerList.
												}
											
											CEntity::PlayerList.at(playerID)->maxHealth = CEntity::PlayerList.at(playerID)->health;	
											}
												break;
										}
									default:
										{
										}
									}
								break;
							}// End packetID case 1. Lobby commands.
					}
				} // End if
			} // End for
		} // End if
	} // End if
} // End Run client

// Send packet function used for movement command packets.
void CClient::SendPacket(int packetID, int entityID, int playerID, int command)
{
	LOGW("Time: " << SDL_GetTicks() << " - " << "Sending none projectile none item packet with command " << command);
	targX = 0;
	targY = 0;
	ToSend.Clear();
	ToSend << packetID;
	ToSend << entityID;
	ToSend << myID;
	ToSend << command;
	ToSend << targX;
	ToSend << targY;

	Client.Send(ToSend);
}

// Send packet function used for projectile packets.
void CClient::SendPacket(int packetID, int entityID, int playerID, int command, int tarX, int tarY,char name[],char items[5])
{
	LOGW("Time: " << SDL_GetTicks() << " - " << "Sending item packet with command " << command);
	ToSend.Clear();
	ToSend << packetID;
	ToSend << entityID;
	ToSend << myID;
	ToSend << command;
	ToSend << tarX;
	ToSend << tarY;
	ToSend << name;
	ToSend << items;
	Client.Send(ToSend);
}

void CClient::SendPacket(int packetID, int entityID, int playerID, int command, int tarX, int tarY)
{
	LOGW("Time: " << SDL_GetTicks() << " - " << "Sending projectile none item packet with command " << command);
	ToSend.Clear();
	ToSend << packetID;
	ToSend << entityID;
	ToSend << myID;
	ToSend << command;
	ToSend << tarX;
	ToSend << tarY;
	Client.Send(ToSend);
}

int CClient::myID = 0;

// ----------------------------------
// Server function
// ----------------------------------

void CClient::RunServer()
{
	if(!connected)
	{
		if (!Server.Listen(Port))
			return;
		selector.Add(Server);

		connected = true;
	}
	if(selector.Wait(0.5f) > 0)
	{
		NbSockets = selector.Wait();
		
		for (unsigned int i = 0; i < NbSockets; ++i)
		{
			Socket = selector.GetSocketReady(i);

			if(Socket == Server)
			{
				// Accept new connections and add them to the selector.
				sf::SocketTCP* Client = new sf::SocketTCP;
				Server.Accept(*Client, &ServerAddress);
				selector.Add(*Client);

				// Clears the onConnect packet of old information, adds the newest playerID to it
				// then sends it to the newly connected client.
				onConnect.Clear();
				onConnect << PID;
				Client->Send(onConnect);
					

				// Currently no use, but for the lobby this will be needed. Sends the ID of the newly connected
				// client to all connected clients. Might need to change the packet structure though, to support
				// disconnects etc.
				// Currently sends empty packet, remove Clear to send just the PID.
				onConnect.Clear();
				packetID = 1;
				entityID = 0;
				playerID = PID;
				command = 0;
				targX = 0;
				targY = 0;
				
				Sockets.push_back(Client);
				onConnect << packetID << entityID << playerID << command << targX << targY;
					
				
				int x = Sockets.size();

				for(int t = 0; t < x; t++)
				{
					Sockets.at(t)->Send(onConnect);
				}
				// -------------------------------------------
					
				CApp::addPlayer();
				// Adds new client to the back of the sockets vector.
				
				
				// Increments playerID.
				PID++;
			}
			else
			{
						
				ReSend.Clear();
				status = Socket.Receive(ReSend);
					
				if(status == sf::Socket::Done)
				{
					// If the packet could be read, resend the packet to all connected clients.
					ReSend >> packetID >> entityID >> playerID >> command >> targX >> targY >> name >> items;
					{
						// Check the packetID
				switch(packetID)
				{	
				case 0: // Packet ID 0, command packet. Currently contains movement and casting commands.
						{
							switch(command)	// Check the commandID. ToDo: Change 0, 1 etc. to the corresponding command name from the ENUM.
							{
							case 0:
							{
								CEntity::PlayerList.at(playerID)->MoveLeft = true;
								targX = CEntity::PlayerList.at(playerID)->X;
								targY = CEntity::PlayerList.at(playerID)->Y;
								break;
							}
						case 1:
							{
								CEntity::PlayerList.at(playerID)->MoveRight = true;
								targX = CEntity::PlayerList.at(playerID)->X;
								targY = CEntity::PlayerList.at(playerID)->Y;
								break;
							}
						case 2:
							{
								CEntity::PlayerList.at(playerID)->Jump();
								targX = CEntity::PlayerList.at(playerID)->X;
								targY = CEntity::PlayerList.at(playerID)->Y;
								break;
							}
						case 3:
							{
								CEntity::PlayerList.at(playerID)->MoveLeft = false;
								targX = CEntity::PlayerList.at(playerID)->X;
								targY = CEntity::PlayerList.at(playerID)->Y;
								break;
							}
						case 4:
							{
								CEntity::PlayerList.at(playerID)->MoveRight = false;
								targX = CEntity::PlayerList.at(playerID)->X;
								targY = CEntity::PlayerList.at(playerID)->Y;
								break;
							}
						case 5:
							{
								/* Testing different jumps with server.
								CEntity::PlayerList.at(playerID)->CanJump = false;
								targX = CEntity::PlayerList.at(playerID)->X;
								targY = CEntity::PlayerList.at(playerID)->Y;
								*/
								break;
							}
						case 6:
							{
								// Projectiles are working as intended in the final versions, it sends the target when Q is clicked
								// So you have to aim when you click Q , instead of being able to move your mouse up
								// until the spell is finished.
								switch(entityID)
								{
									case 0:
										{
											break;
										}
									case 1:
										{
											
											if(!CEntity::PlayerList.at(playerID)->casting)
											{
												CEntity::PlayerList.at(playerID)->casting = true;
												CEntity::PlayerList.at(playerID)->spellID = entityID;
												CEntity::PlayerList.at(playerID)->castStart = SDL_GetTicks();
												CEntity::PlayerList.at(playerID)->targetX = targX;
												CEntity::PlayerList.at(playerID)->targetY = targY;
												CEntity::PlayerList.at(playerID)->castEnd = CEntity::PlayerList.at(playerID)->castStart + 1000;
											}
											break;
										}
									case 2:
										{
											
											if(!CEntity::PlayerList.at(playerID)->casting)
											{
												CEntity::PlayerList.at(playerID)->casting = true;
												CEntity::PlayerList.at(playerID)->spellID = entityID;
												CEntity::PlayerList.at(playerID)->castStart = SDL_GetTicks();
												CEntity::PlayerList.at(playerID)->targetX = targX;
												CEntity::PlayerList.at(playerID)->targetY = targY;
												CEntity::PlayerList.at(playerID)->castEnd = CEntity::PlayerList.at(playerID)->castStart + 1000;
											}
											break;
										}
									case 3:
										{
											if(CEntity::PlayerList.at(playerID)->castSpell4 < SDL_GetTicks())
											{
												CEntity::PlayerList.at(playerID)->castSpell4 = SDL_GetTicks() + 20000;
												CEntity::PlayerList.at(playerID)->flash();
												ReSend.Clear();
												ReSend << packetID << 3 << playerID << 11 << targX << targY << name << items;
												ServerBroadcastPacket(ReSend);
											}
											break;
										}
									case 4:
									{
										if(!CEntity::PlayerList.at(playerID)->casting)
										{
											CEntity::PlayerList.at(playerID)->casting = true;
											CEntity::PlayerList.at(playerID)->spellID = entityID;
											CEntity::PlayerList.at(playerID)->castStart = SDL_GetTicks();
											CEntity::PlayerList.at(playerID)->targetX = targX;
											CEntity::PlayerList.at(playerID)->targetY = targY;
											CEntity::PlayerList.at(playerID)->castEnd = CEntity::PlayerList.at(playerID)->castStart + 500;
										}
										break;
									}
									case 5:
									{
										if(!CEntity::PlayerList.at(playerID)->casting)
										{
											CEntity::PlayerList.at(playerID)->targetX = targX;
											CEntity::PlayerList.at(playerID)->targetY = targY;
											CEntity::PlayerList.at(playerID)->CastProjectile(5);
											ReSend.Clear();
											ReSend << packetID << 5 << playerID << 11 << targX << targY << name << items;
											ServerBroadcastPacket(ReSend);
										}
										break;
									}
								}
							
							break;
							}
							case 7:
							{
							break;		
							}
						default:
							{
							}
						}
						break;
					}
						// End packetID case 0. Movement commands.
					case 1: // Packet ID 1, Lobby packet.
						{
							switch(command)	// Check the commandID. ToDo: Change 0, 1 etc. to the corresponding command name from the ENUM.
							{
								case CONNECT:
								{
									CApp::addPlayer();
									break;
								}
								case DISCONNECT:
								{
									CApp::removePlayer(playerID);
									break;
								}
								case 8:
									{
										
										CEntity::PlayerList.at(playerID)->name = name;
										CEntity::PlayerList.at(playerID)->itemArray[0] = items[0];
										CEntity::PlayerList.at(playerID)->itemArray[1] = items[1];
										CEntity::PlayerList.at(playerID)->itemArray[2] = items[2];
										CEntity::PlayerList.at(playerID)->itemArray[3] = items[3];
										CEntity::PlayerList.at(playerID)->itemArray[4] = items[4];

										if(CEntity::PlayerList.at(playerID)->health == 100)// Checks if playerhealth already has been substracted, this runs everytime a player joins, so the if test if needed.
										{
											for (int i = 0; i < 5; i++)
											{
												#pragma region ItemsEffects
												char cItemID = CEntity::PlayerList.at(playerID)->itemArray[i];
												int iItemID = atoi(&cItemID);
												std::string effect = itemList.effects[iItemID];
									
												//Health
												if(effect.at(0) == '-') 
												{
													CEntity::PlayerList.at(playerID)->health -= atoi(&effect.at(1));
												}
											
												else if(effect.at(0) == '+')
												{
													CEntity::PlayerList.at(playerID)->health += atoi(&effect.at(1));
												}		

												//CastSpeed
												if(effect.at(4) == '-') 
												{	
													if(CEntity::PlayerList.at(playerID)->castTime -= atoi(&effect.at(5))<6)
													{	
														CEntity::PlayerList.at(playerID)->castTime = 5;
													}	
												}
											
												if(effect.at(4) == '+')
												{
													CEntity::PlayerList;
													CEntity::PlayerList.at(playerID)->castTime += atoi(&effect.at(5));		
												}	

												//MoveSpeed
												if(effect.at(8) == '-') 
												{
													if(CEntity::PlayerList.at(playerID)->MaxSpeedX -= atoi(&effect.at(9))< 2)
													{		
														CEntity::PlayerList.at(playerID)->MaxSpeedX = 1;
													}
												}
											
												if(effect.at(8) == '+')
												{
													CEntity::PlayerList;
													CEntity::PlayerList.at(playerID)->MaxSpeedX += atoi(&effect.at(9));	
												}	
												#pragma endregion	
											}	

											CEntity::PlayerList.at(playerID)->maxHealth = CEntity::PlayerList.at(playerID)->health;

										}				
									}
									
								default:
									{
									}
								}

								break;
							}
						// End packetID case 1. Lobby commands.
					}
					if(entityID != 5 ||command != 6)
					{
						ReSend.Clear();
				
						ReSend << packetID << entityID << playerID << command << targX << targY << name << items;
				
						ServerBroadcastPacket(ReSend);
					}
				}
				}
				else if(status == sf::Socket::Disconnected)
				{
					PID --;
					onConnect.Clear();
					packetID = 1;
					entityID = 0;
					command = 1;
					targX = 0;
					targY = 0;
					onConnect << packetID << entityID << playerID << command << targX << targY;

					for(int t = 0; t < Sockets.size(); t++)
					{
						if(Socket == *Sockets.at(t))
						{
							selector.Remove(Socket);
							playerID = t;
						}
					}

					CApp::removePlayer(playerID);
					ServerBroadcastPacket(onConnect);
				}
			}
		}
				
	}
} // End Run Server


bool CClient::ServerBroadcastPacket(sf::Packet sendPacket)
{
	LOGW("Time: " << SDL_GetTicks() << " - " << "Server broadcasting packet");
	for(int t = 0; t < Sockets.size(); t++)
	{
		Sockets.at(t)->Send(sendPacket);
	}
	return true;
}